package com.towexin.config.shiro;

import com.alibaba.fastjson.JSON;
import com.towexin.application.websocket.domain.MessageBody;
import com.towexin.common.ResultData;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * TODO
 * 重写角色认证过滤器，返回页面提示内容
 * 适用于从 config 配置文件配置拦截的过滤
 *
 * @author Towexin
 * @version 1.0
 * @date 2021/5/5 16:31
 */

public class CustomizeRolesAuthorizationFilter extends RolesAuthorizationFilter {
    @Autowired
    private SimpMessageSendingOperations simpMessageSendingOperations;


    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
        Subject subject = this.getSubject(request, response);

        if (subject.getPrincipal() == null) {
            this.saveRequestAndRedirectToLogin(request, response);
        } else {
            MessageBody messageBody = new MessageBody();
            messageBody.setFrom("system");
            messageBody.setContent("没有操作权限");
            messageBody.setTargetUser(subject.getPrincipal().toString());

            simpMessageSendingOperations.convertAndSendToUser(messageBody.getTargetUser(), "/notify/" + messageBody.getTargetUser(), messageBody);


            // 强转为HTTP
            HttpServletRequest req = (HttpServletRequest) request;
            HttpServletResponse resp = (HttpServletResponse)response;
            // 获取响应头中ajax
            String header = req.getHeader("X-Requested-With");
            // 如果是ajax请求
            if ("XMLHttpRequest".equals(header)){
                // 设置响应头
                resp.setContentType("application/json;charset=UTF-8");
                resp.getWriter().write(JSON.toJSONString(ResultData.NO(403, "角色认证失败")));
            }

            if (StringUtils.hasText(this.getUnauthorizedUrl())) {
                WebUtils.issueRedirect(request, response, this.getUnauthorizedUrl());
            } else {
                // 不设置重定向页面时返回html内容
                response.setCharacterEncoding("UTF-8");
                response.setContentType("text/html");
                PrintWriter out = response.getWriter();

                // 1. 创建模板解析器 并设置相关属性
                ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
                // 配置解析器模板存储文件夹路径
                resolver.setPrefix("template-model/");
                // 配置解析器模板文件后缀
                resolver.setSuffix(".html");

                // 通过template模板获取html内容
                TemplateEngine templateEngine = new TemplateEngine();
                templateEngine.setTemplateResolver(resolver);

                // 更新请求的页面的内容为无权限页面
                out.write(templateEngine.process("no-auth", new Context()));
                out.close();
            }
        }
        return Boolean.FALSE;
    }
}
